#include <iostream>
#include <vector>
#include <initializer_list>
/*
initializer_list:
- 当一个类型使用{a;b;c...}进行初始化时会调用initializer_list。
- initializer_list内部所有对象都是const类型。
- for(initializer: list)遍历会自动转换类型为initializer_list。
*/

/*
成员函数、构造函数的赋值：
- 使用 “:”:
	TEST( int AA, int BB )
		:a(AA),b(BB)
	{}
- 直接赋值:
	TEST( int AA, int BB)
	{
		a=AA;
		b=BB;
	}
*/

// 在成员函数后加const，修饰的是this指针的指向的值，让指针指向的值不可以修改

template <typename Object>
class Matrix{
	public:
		Matrix(int rows, int cols)
			// vector(n, elem) 复制n个elem
			:array_(rows, std::vector<Object>(cols, Object{}))
		{}

		Matrix(std::initializer_list<std::vector<Object>> lst)
			// vector(n) 长度为n的vector
			:array_(lst.size())
		{
			int i = 0;
			for(auto& v : lst)
				array_[i++] = std::move(v); // 逐个移入。
		}

		Matrix(const std::vector<std::vector<Object>>& v)
			// vector(const vector &vec) 拷贝vector
			:array_{v}
		{}

		Matrix(std::vector<std::vector<Object>>&& v)
			// vector(const vector &vec) 移动vector
			:array_{std::move(v)}
		{}

		~Matrix() = default; // 编译器自动实现改函数。

		// 重载 get
		const std::vector<Object>& operator[] (int row) const{
			return array_[row];
		}

		// 重载 set
		std::vector<Object>& operator[] (int row){
			return array_[row];
		}

		// 行数
		std::size_t numrows() const{
			return array_.size();
		}
		// 列数
		std::size_t numcols() const{
			return numrows() ? array_[0].size() : 0;
		}

		// 重载 -
		Matrix<Object> operator- (){
			if(!array_.size() or !(array_[0].size()))
				return *this;
			Matrix<Object> mat = *this;
			for(std::size_t row = 0; row < array_.size(); ++row)
				for(std::size_t col = 0; col < array_[0].size(); ++col)
					mat[row][col] = array_[row][col] ? -array_[row][col] : array_[row][col];
			return mat;
		}

		// 重载 +
		Matrix<Object> operator+ (Matrix<Object>& mat0){
			int r1 = this->numrows(), c1 = this->numcols(),
				r2 = mat0.numrows(), c2 = mat0.numcols();
			if(!r1 or !c1)
				return mat0;
			if(!r2 or !c2)
				return *this;
			int r = r1>=r2 ? r1 : r2;
			int c = c1>=c2 ? c1 : c2;
			Matrix<Object> mat = Matrix<Object>(r, c);
			std::size_t row = 0;
			while(row<r1 and row<r2){
				std::size_t col = 0;
				while(col<c1 and col<c2){
					mat[row][col] = array_[row][col]+mat0[row][col];
					col++;
				}
				while(col<c1){
					mat[row][col] = array_[row][col];
					col++;
				}
				while(col<c2){
					mat[row][col] = mat0[row][col];
					col++;
				}
				row++;
			}
			while(row<r1){
				std::size_t col = 0;
				while(col<c1){
					mat[row][col] = array_[row][col];
					col++;
				}
				row++;
			}
			while(row<r2){
				std::size_t col = 0;
				while(col<c2){
					mat[row][col] = mat0[row][col];
					col++;
				}
				row++;
			}
			return mat;
		}

	private:
		// value
		std::vector<std::vector<Object>> array_;
};

// 重载 输出流<<
template <typename Object>
std::ostream& operator<< (std::ostream& os, const Matrix<Object>& mat)
{
	os << '[' << std::endl;
	for(std::size_t row = 0; row < mat.numrows(); ++row){
		os << "  " << '[';
		for(std::size_t col = 0; col < mat.numcols(); ++col)
			os << mat[row][col] << ' ';
		os << ']' << std::endl;
	}
	os << ']';
	return os;
}